package com.mashibing.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mashibing.entity.DriverOrderStatistics;
import com.mashibing.internalcommon.constant.CommonStatusEnum;
import com.mashibing.internalcommon.constant.DriverCarConstants;
import com.mashibing.internalcommon.constant.IdentityConstants;
import com.mashibing.internalcommon.constant.OrderConstants;
import com.mashibing.internalcommon.dto.Car;
import com.mashibing.internalcommon.dto.OrderInfo;
import com.mashibing.internalcommon.dto.PriceRule;
import com.mashibing.internalcommon.dto.ResponseResult;
import com.mashibing.internalcommon.remote.ServiceMapClient;
import com.mashibing.internalcommon.remote.ServiceSsePushClient;
import com.mashibing.internalcommon.request.DriverGrabRequest;
import com.mashibing.internalcommon.request.OrderRequest;
import com.mashibing.internalcommon.request.PriceRuleIsNewRequest;
import com.mashibing.internalcommon.request.PushRequest;
import com.mashibing.internalcommon.response.OrderDriverResponse;
import com.mashibing.internalcommon.response.TerminalResponse;
import com.mashibing.internalcommon.response.TrsearchResponse;
import com.mashibing.internalcommon.util.RedisPrefixUtils;
import com.mashibing.mapper.DriverOrderStatisticsMapper;
import com.mashibing.mapper.OrderInfoMapper;
import com.mashibing.internalcommon.remote.ServicePriceClient;
import com.mashibing.internalcommon.remote.DriverUserClient;
import com.mashibing.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {

    @Autowired
    private ServicePriceClient servicePriceClient;

    @Autowired
    private ServiceMapClient serviceMapClient;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private DriverUserClient serviceDriverUserClient;

    @Autowired
    @Qualifier("redissonBootYml")
    private RedissonClient redissonClient;

    @Autowired
    private ServiceSsePushClient serviceSeeWebClient;

    @Autowired
    private DriverOrderStatisticsMapper driverOrderStatisticsMapper;

    @Override
    public ResponseResult addOrder(OrderRequest orderRequest) {

        // 下单城市有无司机
        ResponseResult<Boolean> availableDriverResult = serviceDriverUserClient.isAvailableDriver(orderRequest.getAddress());
        Boolean ifExist = availableDriverResult.getData();
        log.info("当前司机是否有可用司机：" + ifExist);
        if (!ifExist) {
            return ResponseResult.fail(CommonStatusEnum.CITY_DRIVER_EMPTY.getCode(), CommonStatusEnum.CITY_DRIVER_EMPTY.getMessage(), null);
        }

        // 下单的城市和计价规则是否存在
        if (!isPriceRuleExists(orderRequest)) {
            return ResponseResult.fail(CommonStatusEnum.CITY_SERVICE_NOT_SERVICE.getCode(), CommonStatusEnum.CITY_SERVICE_NOT_SERVICE.getMessage(), null);
        }

        // 乘客黑名单校验
        String deviceCode = orderRequest.getDeviceCode();
        boolean ifDeviceCodeValid = ifDeviceCodeValid(deviceCode);
        if (!ifDeviceCodeValid) {
            return ResponseResult.fail(CommonStatusEnum.DEVICE_IS_BLACK.getCode(), CommonStatusEnum.DEVICE_IS_BLACK.getMessage(), null);
        }

        // 判断是否为最新计价规则，不是最新，提醒乘客重新下单
        PriceRuleIsNewRequest priceRuleIsNewRequest = new PriceRuleIsNewRequest();
        BeanUtils.copyProperties(orderRequest, priceRuleIsNewRequest);
        ResponseResult<Boolean> aNew = servicePriceClient.isNew(priceRuleIsNewRequest);
        if (!aNew.getData()) {
            return ResponseResult.fail(CommonStatusEnum.PRICE_RULE_CHANGED.getCode(), CommonStatusEnum.PRICE_RULE_CHANGED.getMessage(), null);
        }

        // 订单状态校验（只有 订单失效：0，订单支付完成：8，订取消：9 状态下允许下单）
        int count = getPassengerOrderInfoCount(orderRequest.getPassengerId());
        if (count > 0) {
            return ResponseResult.fail(CommonStatusEnum.ORDER_GOING_ON.getCode(), CommonStatusEnum.ORDER_GOING_ON.getMessage(), null);
        }

        // 创建订单
        OrderInfo orderInfo = new OrderInfo();
        BeanUtils.copyProperties(orderRequest, orderInfo);
        orderInfo.setOrderStatus(OrderConstants.ORDER_START);
        LocalDateTime now = LocalDateTime.now();
        orderInfo.setGmtCreate(now);
        orderInfo.setGmtModified(now);
        orderInfoMapper.insert(orderInfo);

        // 定时任务（找不到车，就等待20秒，循环6次）
        for (int i = 0; i < 6; i++) {
            //派送订单(如果已经找到司机，结束循环)
            if (dispatchOrder(orderInfo)) {
                break;
            }

            if (i == 5) {
                // 订单无效
                orderInfo.setOrderStatus(OrderConstants.ORDER_INVALID);
                orderInfoMapper.updateById(orderInfo);
            } else {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        return ResponseResult.success();
    }

    @Override
    public ResponseResult book(OrderRequest orderRequest) {

        // 创建订单
        OrderInfo orderInfo = new OrderInfo();
        BeanUtils.copyProperties(orderRequest, orderInfo);
        orderInfo.setOrderStatus(OrderConstants.ORDER_START);
        LocalDateTime now = LocalDateTime.now();
        orderInfo.setGmtCreate(now);
        orderInfo.setGmtModified(now);
        orderInfoMapper.insert(orderInfo);

        // 完善订单
        bookOrder(orderInfo);

        return ResponseResult.success();
    }

    @Override
    @Transactional
    public ResponseResult driverGrab(DriverGrabRequest driverGrabRequest) {
        Long driverId = driverGrabRequest.getDriverId();
        System.out.println("请求来了：" + driverId);

        Long orderId = driverGrabRequest.getOrderId();
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if (orderInfo == null) {
            return ResponseResult.fail(CommonStatusEnum.ORDER_NOT_EXISTS.getCode(), CommonStatusEnum.ORDER_NOT_EXISTS.getMessage(), null);
        }

        int orderStatus = orderInfo.getOrderStatus();
        if (orderStatus != OrderConstants.ORDER_START) {
            return ResponseResult.fail(CommonStatusEnum.ORDER_CAN_NOT_GRAB.getCode(), CommonStatusEnum.ORDER_CAN_NOT_GRAB.getMessage(), null);
        }

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        BeanUtils.copyProperties(driverGrabRequest, orderInfo);
        orderInfo.setOrderStatus(OrderConstants.DRIVER_RECEIVE_ORDER);
        orderInfoMapper.updateById(orderInfo);

        // 新增功能，记录司机抢单成功的数量
        QueryWrapper<DriverOrderStatistics> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("grab_order_date", LocalDate.now());
        queryWrapper.eq("driver_id", driverId);
        DriverOrderStatistics driverOrderStatistics = driverOrderStatisticsMapper.selectOne(queryWrapper);
        if (driverOrderStatistics == null) {
            driverOrderStatistics = new DriverOrderStatistics();
            driverOrderStatistics.setGrabOrderDate(LocalDate.now());
            driverOrderStatistics.setGrabOrderSuccessCount(1);
            driverOrderStatistics.setDriverId(driverId);
            driverOrderStatisticsMapper.insert(driverOrderStatistics);
        } else {
            driverOrderStatistics.setGrabOrderSuccessCount(driverOrderStatistics.getGrabOrderSuccessCount() + 1);
            driverOrderStatisticsMapper.updateById(driverOrderStatistics);
        }
        return ResponseResult.success();
    }


    /**
     * 派送订单
     *
     * @param orderInfo 订单信息
     * @return
     */
    public boolean dispatchOrder(OrderInfo orderInfo) {
        log.info("循环一次");
        boolean ifDriverExist = false;

        String depLatitude = orderInfo.getDepLatitude();
        String depLongitude = orderInfo.getDepLongitude();
        String center = depLatitude + "," + depLongitude;

        List<Integer> radiusList = Arrays.asList(2000, 4000, 5000);
        for (Integer radius : radiusList) {
            // 获取地图查询结果
            ResponseResult<List<TerminalResponse>> listResponseResult = serviceMapClient.aroundSearch(center, radius);
            List<TerminalResponse> data = listResponseResult.getData();

            // 解析结果
            for (TerminalResponse terminalResponse : data) {
                // 获取carId
                Long carId = terminalResponse.getCarId();

                // 根据carId获取与之绑定的司机状态(调用service-driver-user)
                ResponseResult<OrderDriverResponse> driverUserInfoByCarIdResult = serviceDriverUserClient.getDriverUserInfoByCarId(carId.toString());
                OrderDriverResponse orderDriverResponse = driverUserInfoByCarIdResult.getData();
                Long driverId = orderDriverResponse.getDriverId();

                // 司机不是出车状态,跳出循环，是出车状态，继续流程
                if (!(DriverCarConstants.DRIVER_WORK_STATUS_START == orderDriverResponse.getWorkStatus())) {
                    log.info("当前车辆carId{}对应司机：{}没有出车", carId, driverId);
                    continue;
                }

                String lockKey = driverId.toString().intern();
                RLock lock = redissonClient.getLock(lockKey);
                lock.lock();

                // 判断司机当前订单状态
                if (getDriverOrderInfoCount(driverId) > 0) {
                    log.info("当前车辆carId{}对应司机：{}有其他订单正在进行", carId, driverId);
                    lock.unlock();
                    continue;
                }

                // 开始派单（修改订单信息）
                // driverUser中查询
                orderInfo.setCarId(carId);
                orderInfo.setDriverId(driverId);
                orderInfo.setDriverPhone(orderDriverResponse.getDriverPhone());
                // map中查询
                orderInfo.setReceiveOrderCarLongitude(terminalResponse.getLongitude());
                orderInfo.setReceiveOrderCarLatitude(terminalResponse.getLatitude());

                orderInfo.setReceiveOrderTime(LocalDateTime.now());
                orderInfo.setLicenseId(orderDriverResponse.getLicenseId());
                orderInfo.setVehicleNo(orderDriverResponse.getVehicleNo());
                orderInfo.setOrderStatus(OrderConstants.DRIVER_RECEIVE_ORDER);

                orderInfoMapper.updateById(orderInfo);

                // 通知司机
                notifyDriverUser(orderInfo, driverId);

                // 通知乘客
                notifyPassenger(orderInfo, carId);

                ifDriverExist = true;
                lock.unlock();
                break;
            }
        }
        return ifDriverExist;
    }

    public boolean bookOrder(OrderInfo orderInfo) {

        boolean ifDriverExist = false;

        String depLatitude = orderInfo.getDepLatitude();
        String depLongitude = orderInfo.getDepLongitude();
        String center = depLatitude + "," + depLongitude;

        List<Integer> radiusList = Arrays.asList(2000, 4000, 5000);
        radius:
        for (Integer radius : radiusList) {
            // 获取地图查询结果
            ResponseResult<List<TerminalResponse>> listResponseResult = serviceMapClient.aroundSearch(center, radius);
            List<TerminalResponse> data = listResponseResult.getData();

            // 解析结果
            for (TerminalResponse terminalResponse : data) {
                // 获取carId
                Long carId = terminalResponse.getCarId();

                // 根据carId获取与之绑定的司机状态(调用service-driver-user)
                ResponseResult<OrderDriverResponse> driverUserInfoByCarIdResult = serviceDriverUserClient.getDriverUserInfoByCarId(carId.toString());
                OrderDriverResponse orderDriverResponse = driverUserInfoByCarIdResult.getData();
                Long driverId = orderDriverResponse.getDriverId();

                // 司机不是出车状态,跳出循环，是出车状态，继续流程
                if (!(DriverCarConstants.DRIVER_WORK_STATUS_START == orderDriverResponse.getWorkStatus())) {
                    log.info("当前车辆carId{}对应司机：{}没有出车", carId, driverId);
                    continue;
                }

                // 通知司机
                notifyDriverUser(orderInfo, driverId);
                ifDriverExist = true;
                break radius;
            }
        }
        return ifDriverExist;
    }

    @Override
    public ResponseResult toPickUpPassenger(OrderRequest orderRequest) {
        Long orderId = orderRequest.getOrderId();
        String toPickUpPassengerLongitude = orderRequest.getToPickUpPassengerLongitude();
        String toPickUpPassengerLatitude = orderRequest.getToPickUpPassengerLatitude();
        String toPickUpPassengerAddress = orderRequest.getToPickUpPassengerAddress();

        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);

        orderInfo.setToPickUpPassengerAddress(toPickUpPassengerAddress);
        orderInfo.setToPickUpPassengerLatitude(toPickUpPassengerLatitude);
        orderInfo.setToPickUpPassengerLongitude(toPickUpPassengerLongitude);
        orderInfo.setToPickUpPassengerTime(LocalDateTime.now());
        orderInfo.setOrderStatus(OrderConstants.DRIVER_TO_PICK_UP_PASSENGER);

        orderInfoMapper.updateById(orderInfo);

        return ResponseResult.success();
    }

    @Override
    public ResponseResult arrivedDeparture(OrderRequest orderRequest) {
        Long orderId = orderRequest.getOrderId();

        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        orderInfo.setOrderStatus(OrderConstants.DRIVER_ARRIVED_DEPARTURE);

        orderInfo.setDriverArrivedDepartureTime(LocalDateTime.now());
        orderInfoMapper.updateById(orderInfo);
        return ResponseResult.success();
    }

    @Override
    public ResponseResult pickUpPassenger(OrderRequest orderRequest) {
        Long orderId = orderRequest.getOrderId();
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);

        orderInfo.setPickUpPassengerLongitude(orderRequest.getPickUpPassengerLongitude());
        orderInfo.setPickUpPassengerLatitude(orderRequest.getPickUpPassengerLatitude());
        orderInfo.setPickUpPassengerTime(LocalDateTime.now());
        orderInfo.setOrderStatus(OrderConstants.PICK_UP_PASSENGER);

        orderInfoMapper.updateById(orderInfo);
        return ResponseResult.success();
    }

    @Override
    public ResponseResult passengerGetOff(OrderRequest orderRequest) {
        Long orderId = orderRequest.getOrderId();
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);

        orderInfo.setPassengerGetoffTime(LocalDateTime.now());
        orderInfo.setPassengerGetoffLongitude(orderRequest.getPassengerGetoffLongitude());
        orderInfo.setPassengerGetoffLatitude(orderRequest.getPassengerGetoffLatitude());
        orderInfo.setOrderStatus(OrderConstants.PASSENGER_GETOFF);

        ResponseResult<Car> carById = serviceDriverUserClient.getDriverById(orderInfo.getCarId().toString());
        long startTime = orderInfo.getPickUpPassengerTime().toInstant(ZoneOffset.of("+8")).toEpochMilli();
        long endTime = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();

        System.out.println("开始时间：" + startTime);
        System.out.println("结束时间：" + endTime);

        // 订单行驶的路程和时间,调用 service-map
        // 1668078028000l,测试的时候不要跨天
        ResponseResult<TrsearchResponse> trackSearch = serviceMapClient.trackSearch(carById.getData().getTid(), startTime, endTime);
        TrsearchResponse data = trackSearch.getData();

        if (null != data) {
            orderInfo.setDriveMile(data.getDriveMile());
            orderInfo.setDriveTime(data.getDriveTime());

            // 计算价格
            ResponseResult<Double> result = servicePriceClient.calculatePrice(data.getDriveMile().intValue(), data.getDriveTime().intValue(), orderInfo.getAddress(), orderInfo.getVehicleType());
            Double price = result.getData();
            orderInfo.setPrice(price);

            orderInfoMapper.updateById(orderInfo);
        }

        return ResponseResult.success();
    }

    @Override
    public ResponseResult pay(OrderRequest orderRequest) {
        Long orderId = orderRequest.getOrderId();
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);

        orderInfo.setOrderStatus(OrderConstants.SUCCESS_PAY);
        orderInfoMapper.updateById(orderInfo);
        return ResponseResult.success();
    }

    @Override
    public ResponseResult cancel(Long orderId, String identity) {
        // 查询订单当前状态
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        Integer orderStatus = orderInfo.getOrderStatus();

        LocalDateTime cancelTime = LocalDateTime.now();
        Integer cancelTypeCode = null;

        // 正常取消
        int cancelType = 1;

        // 更新订单的取消状态
        // 如果是乘客取消
        if (identity.trim().equals(IdentityConstants.PASSENGER_IDENTITY)) {
            switch (orderStatus) {
                // 订单开始
                case OrderConstants.ORDER_START:
                    cancelTypeCode = OrderConstants.CANCEL_PASSENGER_BEFORE;
                    break;
                // 司机接到订单
                case OrderConstants.DRIVER_RECEIVE_ORDER:
                    LocalDateTime receiveOrderTime = orderInfo.getReceiveOrderTime();
                    long between = ChronoUnit.MINUTES.between(receiveOrderTime, cancelTime);
                    if (between > 1) {
                        cancelTypeCode = OrderConstants.CANCEL_PASSENGER_ILLEGAL;
                    } else {
                        cancelTypeCode = OrderConstants.CANCEL_PASSENGER_BEFORE;
                    }
                    break;
                // 司机去接乘客
                case OrderConstants.DRIVER_TO_PICK_UP_PASSENGER:
                    // 司机到达乘客起点
                case OrderConstants.DRIVER_ARRIVED_DEPARTURE:
                    cancelTypeCode = OrderConstants.CANCEL_PASSENGER_ILLEGAL;
                    break;
                default:
                    log.info("乘客取消失败");
                    cancelType = 0;
                    break;
            }
        }

        // 如果是司机取消
        if (identity.trim().equals(IdentityConstants.DRIVER_IDENTITY)) {
            switch (orderStatus) {
                // 订单开始
                // 司机接到乘客
                case OrderConstants.DRIVER_RECEIVE_ORDER:
                case OrderConstants.DRIVER_TO_PICK_UP_PASSENGER:
                case OrderConstants.DRIVER_ARRIVED_DEPARTURE:
                    LocalDateTime receiveOrderTime = orderInfo.getReceiveOrderTime();
                    long between = ChronoUnit.MINUTES.between(receiveOrderTime, cancelTime);
                    if (between > 1) {
                        cancelTypeCode = OrderConstants.CANCEL_DRIVER_ILLEGAL;
                    } else {
                        cancelTypeCode = OrderConstants.CANCEL_DRIVER_BEFORE;
                    }
                    break;

                default:
                    log.info("司机取消失败");
                    cancelType = 0;
                    break;
            }
        }


        if (cancelType == 0) {
            return ResponseResult.fail(CommonStatusEnum.ORDER_CANCEL_ERROR.getCode(), CommonStatusEnum.ORDER_CANCEL_ERROR.getMessage(), null);
        }

        orderInfo.setCancelTypeCode(cancelTypeCode);
        orderInfo.setCancelTime(cancelTime);
        orderInfo.setCancelOperator(Integer.parseInt(identity));
        orderInfo.setOrderStatus(OrderConstants.ORDER_CANCEL);

        orderInfoMapper.updateById(orderInfo);
        return ResponseResult.success();
    }

    @Override
    public ResponseResult pushPayInfo(OrderRequest orderRequest) {
        Long orderId = orderRequest.getOrderId();
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        orderInfo.setOrderStatus(OrderConstants.TO_START_PAY);
        orderInfoMapper.updateById(orderInfo);
        return ResponseResult.success();
    }

    @Override
    public ResponseResult<OrderInfo> detail(Long orderId) {
        return ResponseResult.success(orderInfoMapper.selectById(orderId));
    }


    // 通知乘客
    private void notifyPassenger(OrderInfo orderInfo, Long carId) {
        JSONObject passengerContent = new JSONObject();
        passengerContent.put("orderId", orderInfo.getId());
        passengerContent.put("driverId", orderInfo.getDriverId());
        passengerContent.put("driverPhone", orderInfo.getDriverPhone());
        passengerContent.put("vehicleNo", orderInfo.getVehicleNo());
        passengerContent.put("receiveOrderCarLongitude", orderInfo.getReceiveOrderCarLongitude());
        passengerContent.put("receiveOrderCarLatitude", orderInfo.getReceiveOrderCarLatitude());

        // 车辆信息，调用车辆服务
        ResponseResult<Car> carById = serviceDriverUserClient.getDriverById(carId.toString());
        Car carRemote = carById.getData();

        passengerContent.put("brand", carRemote.getBrand());
        passengerContent.put("model", carRemote.getModel());
        passengerContent.put("vehicleColor", carRemote.getVehicleColor());

        PushRequest pushPassengerRequest = new PushRequest();
        pushPassengerRequest.setUserId(orderInfo.getPassengerId());
        pushPassengerRequest.setIdentity(IdentityConstants.PASSENGER_IDENTITY);
        pushPassengerRequest.setContent(passengerContent.toString());

        serviceSeeWebClient.push(pushPassengerRequest);
    }

    /**
     * 通知司机
     *
     * @param orderInfo
     */
    private void notifyDriverUser(OrderInfo orderInfo, Long driverId) {
        JSONObject driverContent = new JSONObject();

        driverContent.put("orderId", orderInfo.getId());
        driverContent.put("passengerId", orderInfo.getPassengerId());
        driverContent.put("passengerPhone", orderInfo.getPassengerPhone());
        driverContent.put("departure", orderInfo.getDeparture());
        driverContent.put("depLongitude", orderInfo.getDepLongitude());
        driverContent.put("depLatitude", orderInfo.getDepLatitude());
        driverContent.put("destination", orderInfo.getDestination());
        driverContent.put("destLongitude", orderInfo.getDestLongitude());
        driverContent.put("destLatitude", orderInfo.getDestLatitude());

        PushRequest pushRequest = new PushRequest();
        pushRequest.setUserId(driverId);
        pushRequest.setIdentity(IdentityConstants.DRIVER_IDENTITY);
        pushRequest.setContent(driverContent.toString());

        serviceSeeWebClient.push(pushRequest);
    }

    private boolean isPriceRuleExists(OrderRequest orderRequest) {
        String fareType = orderRequest.getFareType();
        int index = fareType.indexOf("$");
        String cityCode = fareType.substring(0, index);
        String vehicleType = fareType.substring(index + 1);

        PriceRule priceRule = new PriceRule();
        priceRule.setCityCode(cityCode);
        priceRule.setVehicleType(vehicleType);

        ResponseResult<Boolean> booleanResponseResult = servicePriceClient.ifExists(priceRule);
        return booleanResponseResult.getData();
    }

    public int getPassengerOrderInfoCount(Long passengerId) {
        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("passenger_id", passengerId);
        queryWrapper.and(wrapper ->
                wrapper.eq("order_status", OrderConstants.ORDER_START)
                        .or().eq("order_status", OrderConstants.DRIVER_RECEIVE_ORDER)
                        .or().eq("order_status", OrderConstants.DRIVER_TO_PICK_UP_PASSENGER)
                        .or().eq("order_status", OrderConstants.DRIVER_ARRIVED_DEPARTURE)
                        .or().eq("order_status", OrderConstants.PICK_UP_PASSENGER)
                        .or().eq("order_status", OrderConstants.PASSENGER_GETOFF)
                        .or().eq("order_status", OrderConstants.TO_START_PAY)
        );
        return orderInfoMapper.selectCount(queryWrapper);
    }

    public int getDriverOrderInfoCount(Long driverId) {
        QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("driver_id", driverId);
        queryWrapper.and(wrapper ->
                wrapper.eq("order_status", OrderConstants.DRIVER_RECEIVE_ORDER)
                        .or().eq("order_status", OrderConstants.DRIVER_TO_PICK_UP_PASSENGER)
                        .or().eq("order_status", OrderConstants.DRIVER_ARRIVED_DEPARTURE)
                        .or().eq("order_status", OrderConstants.PICK_UP_PASSENGER)
        );
        return orderInfoMapper.selectCount(queryWrapper);
    }

    public boolean ifDeviceCodeValid(String deviceCode) {
        // 组装redisKey
        String blackUserKey = RedisPrefixUtils.blackDeviceCodePrefix + deviceCode;
        // 查询redis中有无key
        Boolean hasKey = stringRedisTemplate.hasKey(blackUserKey);

        if (Boolean.TRUE.equals(hasKey)) {
            // 有key，判断是否已达2次
            String value = stringRedisTemplate.opsForValue().get(blackUserKey);
            assert value != null;
            int intValue = Integer.parseInt(value);
            if (intValue >= 2) {
                // 已达2次，报错
                return false;
            }
            // 未达2次，次数加一
            stringRedisTemplate.opsForValue().increment(blackUserKey);
        } else {
            // 无key，新建key，并设置过期时间
            stringRedisTemplate.opsForValue().setIfAbsent(blackUserKey, "1", 1, TimeUnit.HOURS);
        }
        return true;
    }
}
